package com.kahriboo.log4mon.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.kahriboo.log4mon.shared.LogEventShared;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.HeaderControls;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.VisibilityMode;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.HeaderControl;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.FilterBuilder;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler;
import com.smartgwt.client.widgets.grid.events.SelectionEvent;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.SectionStack;
import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.layout.VStack;

public class LogWindow extends Window {

	final ListGrid countryGrid = new ListGrid();
	final HTMLFlow htmlDetails = new HTMLFlow();

	public LogWindow() {
		final ClickHandler clickHandler = new ClickHandler() {
			public void onClick(final ClickEvent event) {
				final String src = ((HeaderControl) event.getSource()).getSrc();
				SC.say("Control " + src + " clicked");
			}
		};

		final HeaderControl arrowDown = new HeaderControl(HeaderControl.ARROW_DOWN, clickHandler);
		final HeaderControl arrowLeft = new HeaderControl(HeaderControl.ARROW_LEFT, clickHandler);
		final HeaderControl arrowRight = new HeaderControl(HeaderControl.ARROW_RIGHT, clickHandler);
		final HeaderControl arrowUp = new HeaderControl(HeaderControl.ARROW_UP, clickHandler);
		final HeaderControl calculator = new HeaderControl(HeaderControl.CALCULATOR, clickHandler);
		final HeaderControl cart = new HeaderControl(HeaderControl.CART, clickHandler);

		setTitle("Title");
		this.setWidth(640);
		this.setHeight(480);
		setCanDragReposition(true);
		setCanDragResize(true);
		setAnimateMinimize(true);

		setHeaderControls(HeaderControls.HEADER_LABEL, arrowDown, arrowLeft, arrowRight, arrowUp, calculator, cart);

		final SectionStack sectionStack = new SectionStack();
		sectionStack.setVisibilityMode(VisibilityMode.MULTIPLE);
		sectionStack.setWidth100();
		sectionStack.setHeight100();
		sectionStack.setCanResizeSections(true);

		final SectionStackSection sectionFilters = new SectionStackSection("Filters");
		sectionFilters.setExpanded(true);
		sectionFilters.setCanCollapse(true);
		sectionFilters.addItem(getFiltersStack());
		sectionStack.addSection(sectionFilters);

		final SectionStackSection sectionLogs = new SectionStackSection("Logs Entries");
		sectionLogs.setExpanded(true);
		sectionLogs.setCanCollapse(false);
		sectionLogs.addItem(getLogsStack());
		sectionStack.addSection(sectionLogs);

		htmlDetails.setOverflow(Overflow.AUTO);
		htmlDetails.setPadding(10);
		setDetailsStack(null);

		final SectionStackSection sectionDetails = new SectionStackSection("Details");
		sectionDetails.setExpanded(true);
		sectionDetails.setCanCollapse(true);
		sectionDetails.addItem(htmlDetails);
		sectionStack.addSection(sectionDetails);

		this.addItem(sectionStack);

	}

	public Canvas getFiltersStack() {

		final FilterBuilder filterBuilder = new FilterBuilder();
		filterBuilder.setDataSource(LogEventData.getDataSourceSchema());

		final IButton filterButton = new IButton("Filter");
		filterButton.addClickHandler(new ClickHandler() {
			public void onClick(final ClickEvent event) {
				final LogEventServiceAsync logEventService = (LogEventServiceAsync) GWT.create(LogEventService.class);

				final AsyncCallback<LogEventShared[]> callback = new AsyncCallback<LogEventShared[]>() {
					public void onSuccess(final LogEventShared[] result) {

						final LogEventRecord[] converted = LogEventData.convert(result);
						htmlDetails.setContents("success !!! size = " + converted.length + " " + converted[0].getMessage());

						countryGrid.setData(converted);
						countryGrid.redraw();
					}

					public void onFailure(final Throwable caught) {
						htmlDetails.setContents("error : " + caught.getMessage());
						// do some UI stuff to show failure
					}
				};

				countryGrid.setData((Record[]) null);
				logEventService.getLogEvents(null, callback);
			}
		});

		final DynamicForm form = new DynamicForm();
		form.setWidth(250);

		final TextItem usernameItem = new TextItem();
		usernameItem.setTitle("Fetch Size");
		usernameItem.setRequired(true);
		usernameItem.setDefaultValue("200");
		form.setFields(new FormItem[] { usernameItem });

		final VStack criteriaFilterCanvas = new VStack(10);
		criteriaFilterCanvas.addMember(filterBuilder);
		criteriaFilterCanvas.addMember(form);
		criteriaFilterCanvas.addMember(filterButton);
		return criteriaFilterCanvas;
	}

	public Canvas getLogsStack() {

		countryGrid.setWidth100();
		countryGrid.setShowAllRecords(true);
		countryGrid.setAutoFetchData(true);

		final ListGridField timeStampField = new ListGridField("timeStamp", "TimeStamp");
		final ListGridField levelField = new ListGridField("level", "Level");
		final ListGridField threadNameField = new ListGridField("threadName", "Thread");
		final ListGridField classNameField = new ListGridField("className", "Class");
		final ListGridField methodNameField = new ListGridField("methodName", "Method");
		final ListGridField fileNameField = new ListGridField("fileName", "File");
		final ListGridField lineNumberField = new ListGridField("lineNumber", "Line");
		final ListGridField loggerNameField = new ListGridField("loggerName", "Logger");
		final ListGridField messageField = new ListGridField("message", "Message");
		final ListGridField throwableClassField = new ListGridField("throwableClass", "Throwable Class");

		countryGrid.setFields(timeStampField, levelField, threadNameField, classNameField, methodNameField, fileNameField, lineNumberField, loggerNameField, messageField, throwableClassField);
		countryGrid.setCanResizeFields(true);

		countryGrid.addSelectionChangedHandler(new SelectionChangedHandler() {
			public void onSelectionChanged(final SelectionEvent event) {
				setDetailsStack(event.getRecord());
			}
		});

		final Button previousButton = new Button("Previous");
		previousButton.setWidth("150");

		final Label navigationLabel = new Label("Record 0 to 100");
		navigationLabel.setWidth("*");
		navigationLabel.setAlign(Alignment.CENTER);

		final Button nextButton = new Button("Next");
		nextButton.setWidth("150");
		final HLayout navigationCanvas = new HLayout();
		navigationCanvas.setWidth100();
		navigationCanvas.setPadding(2);
		navigationCanvas.addMember(previousButton);
		navigationCanvas.addMember(navigationLabel);
		navigationCanvas.addMember(nextButton);

		final VLayout gridCanvas = new VLayout();
		navigationCanvas.setHeight(previousButton.getHeight() + 4);
		countryGrid.setHeight("*");

		gridCanvas.addMember(countryGrid);
		gridCanvas.addMember(navigationCanvas);

		return gridCanvas;
	}

	public void setDetailsStack(final Record data) {
		String contents;
		if (data == null) {
			contents = "<b>Select an event to get some details here.</b>";
		} else {
			// TODO
			contents = "<b>Selected log :</b> " + data.getAttribute("timeStamp");
		}
		htmlDetails.setContents(contents);
	}
}
